package com.seanLab.service;

import com.seanLab.domain.Article;
import com.seanLab.domain.Image;
import com.seanLab.domain.TagInfo;
import com.seanLab.dto.SuggestArticleKeywordsDto;
import com.seanLab.dto.SuggestModelArticleDto;
import com.seanLab.repository.ArticleRepo;
import com.seanLab.repository.ImageRepo;
import com.seanLab.tool.DataExtractor;
import com.seanLab.tool.TagSuggestModel.StaticModelProperties;
import com.seanLab.tool.TagSuggestor;
import com.seanLab.tool.es.ESImageSearch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * Created by ailly on 17-10-9.
 */
@Service
public class DataService {
    @Autowired
    private ArticleRepo articleRepo;

    @Autowired
    private ImageRepo imageRepo;

    @Autowired
    private ESImageSearch esImageSearch;

    private TagSuggestor ts;

    private Article extractKeywordsFromArticle(Article article) {
        Article tmpArticle = article;
        //@吴小波 TagSuggestor应返回该文章对应的关键词. e.g., articleTagList
        //@吴小波 填充以下代码
        //TagSuggestor t1 = new TagSuggestor();
        //SuggestModelArticleDto suggestModelArticleDto = DataExtractor.extractModelArticleFromArticle(article);
        //List<String> keywords = t1.doKeyword(suggestModelArticleDto);

        //fake data
        //List<String> keywords = new ArrayList<String>(Arrays.asList("keyword1", "keyword2"));

        //FIXME 吴晓波代码实现部分（not reviewed）
        TagSuggestor ts = new TagSuggestor();
        ts.loadModel(StaticModelProperties.ModelPath);
        SuggestModelArticleDto suggestModelArticleDto = DataExtractor.extractModelArticleWithoutImgsFromArticle(article);
        List<SuggestArticleKeywordsDto> keywords = ts.doKeyword(suggestModelArticleDto);

        tmpArticle.setKeywords(keywords);
        return tmpArticle;
    }

    private List<Image> extractImgTagsFromArticle(Article article, List<Image> imageList) {
        List<Image> tmpImgList = new ArrayList<Image>(imageList);
        //抽取图片关键词

        //ArrayList<ArrayList<TagInfo>> articleTagList = new ArrayList<ArrayList<TagInfo>>();
        //List<TagInfo> imgTagList = new ArrayList<>();

        // @吴小波 TagSuggestor应返回该文章对应的图片的标签列表. e.g., articleTagList
        // @吴小波 填充以下代码
        //TagSuggestor t1 = new TagSuggestor();
        //SuggestModelArticleDto suggestModelArticleDto = DataExtractor.extractModelArticleFromArticle(article);
        //ArrayList<ArrayList<TagInfo>> articleTagList = t1.doTag(suggestModelArticleDto);

        //FIXME 吴晓波代码实现部分（not reviewed）
//        TagSuggestor ts = new TagSuggestor();
//        ts.loadModel(StaticModelProperties.ModelPath);
        TagSuggestor ts = this.ts;
        SuggestModelArticleDto suggestModelArticleDto = DataExtractor.extractModelArticleFromArticle(article, imageList);

        long start = System.currentTimeMillis();

        List<List<TagInfo>> articleTagList = ts.doTag(suggestModelArticleDto);

        long end = System.currentTimeMillis();
        long cost = end - start;

        for (Image tmpImg : tmpImgList) {
            //FIXME 吴晓波代码实现部分（not reviewed）
            int index = tmpImgList.indexOf(tmpImg);
            tmpImg.setImgTagList(articleTagList.get(index));

        }
        return tmpImgList;
    }

    //从已有article(信息完整，除了keywords)中抽取图片标签
    //测试用代码：基于已经清洗好的article和image抽取标签
    public void extractImgTagsFromExistArticleTest() {
        //FIXME 吴晓波初始化
        this.ts = new TagSuggestor();
        this.ts.loadModel(StaticModelProperties.ModelPath);

        //取出所有的article
        //计时
        long start = System.currentTimeMillis();

//        List<Article> existArticleList = this.articleRepo.findAll();
        List<Article> existArticleList = this.articleRepo.findByExtractImgFlag();

        long end = System.currentTimeMillis();
        long cost = end - start;
        System.out.println("待抽取标签文章查询完毕，耗时： " + cost / 1000 + "s");

        //TODO 多线程测试
        BlockingDeque<Article> tmpArticleQueue = new LinkedBlockingDeque<>(existArticleList);

        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < 8; i++) {
            exec.execute(new RunImageTagging(tmpArticleQueue, this.articleRepo, this.imageRepo) );
        }

        start = System.currentTimeMillis();

//        for (Article tmpExistArticle : existArticleList) {
//            //取出一个article中的imageList
//            List<Image> tmpImageList = new ArrayList<>();
//            for (String tmpImgID : tmpExistArticle.getImgID()) {
//                Image tmpImage = this.imageRepo.findByImgID(tmpImgID);
//                tmpImageList.add(tmpImage);
//            }
//            //抽取图片标签
//            List<Image> tmpImageListWithTags = this.extractImgTagsFromArticle(tmpExistArticle, tmpImageList);
//            //更新图片的标签
//            this.imageRepo.save(tmpImageListWithTags);
//
//            //更新文章关键词
//            Article tmpArticleWithKeywords = this.extractKeywordsFromArticle(tmpExistArticle);
//            tmpArticleWithKeywords.setExtractImgFlag(1);
//            this.articleRepo.save(tmpArticleWithKeywords);
//        }

        end = System.currentTimeMillis();
        cost = end - start;
        System.out.println("抽取图片标签完毕，耗时： " + cost / 1000 + "s");

    }

    //将新增的image记录同步至ES
    public int loadImagesToES() {
        ESImageSearch esImageSearch = this.esImageSearch;
        esImageSearch.initConnection();

        //记录操作时间
        long start = System.currentTimeMillis();

        //TODO 取出flag为0的图片记录（且imgTagList不为空）
        List<Image> ilist = this.imageRepo.findByImgTagListAndEsFlag(new ArrayList<TagInfo>());

        long end = System.currentTimeMillis();
        long time = (end - start) / 1000;

        //TODO @张帆 es相关代码需根据image修改
        esImageSearch.insertImageList(ilist);

        //TODO 导入es后更新flag
        for (Image i : ilist) {
            i.setEsFlag(1);
        }
        this.imageRepo.save(ilist);

        return 0;
    }
}
